<?php


namespace wxpay;
use think\Db;

class Delivery
{
    // 正式环境 https://sfapi.sf-express.com
    // 沙箱环境 https://sfapi-sbox.sf-express.com
    protected $url = 'https://sfapi-sbox.sf-express.com';
    protected $partnerid = 'ACTWLiPz9EgL'; // 顾客编码
    protected $secret = 'PaC3AomrLBEZNV6DJlRP9una9gZD7db4'; //秘钥
    protected $granttype = 'password';


    /**
     * 获取签名
     */
    public function sfAccesstoken()
    {
        $authToken = Db::name('auth_token');
        $sfapiData = $authToken->where('type','sfapi')->find();
        $time = time();
        $seconds = 3600 * 2;
        if (empty($sfapiData))
        {
            $accesstoken = $this->accessTokne();
            if (empty($accesstoken))
            {
                return false;
            }
            $authToken->insert([
                'type' => 'sfapi',
                'asscesstoken' => $accesstoken['accessToken'],
                'appid' => $accesstoken['apiResponseID'],
                'createtime'   => $time,
                'updatetime'   => $time + $seconds
            ]);
            $response = [
                'requestID' => $accesstoken['apiResponseID'],
                'accessToken' => $accesstoken['accessToken']
            ];
            return $response;
        }

        if ($sfapiData['updatetime'] <= $time)
        {
            $accesstoken = $this->accessTokne();
            $authToken->where('type','sfapi')->update([
                'asscesstoken' => $accesstoken['accessToken'],
                'appid' => $accesstoken['apiResponseID'],
                'updatetime'   => $time + $seconds
            ]);
            $response = [
                'requestID' => $accesstoken['apiResponseID'],
                'accessToken' => $accesstoken['accessToken']
            ];
        }else{
            $response = [
                'requestID' => $sfapiData['appid'],
                'accessToken' => $sfapiData['asscesstoken']
            ];
        }

        return $response;
    }

    /**
     * @return false|mixed
     * 获取token
     */
    public function accessTokne()
    {
        $post_url = $this->url.'/oauth2/accessToken';
        $post_data = [
            'partnerID' => $this->partnerid,
            'grantType' => $this->granttype,
            'secret'    => $this->secret
        ];
        $data = request_url($post_url,$post_data);
        $data = json_decode($data,true);

        if ($data['apiResultCode'] == "A1000" && $data['apiErrorMsg'] == 'success')
        {
            return $data;
        }else{
            return false;
        }
    }

    /**
     * 下单接口
     * $order 订单信息
     * $courier 发货信息
     * $admin_id 操作人员
     * $payMethod 付款方式，支持以下值： 1:寄方付 2:收方付
     */
    public function placeOrder($order,$courier_id,$admin_id,$payMethod)
    {

        $result = [
            'data'   => [],
            'msg'    =>'',
            'status' => false
        ];
        $asscessToken = $this->sfAccesstoken();
        if (empty($asscessToken))
        {
            $result['msg'] = '认证获取失败';
            return $result;
        }

        $courierData = Db::name('courier')
            ->where('id',$courier_id)
            ->find();

        $courier = [
            'contactType' => 1,
            'company'   =>  $courierData['company'],
            'contact'   =>  $courierData['name'],
            'tel'       =>  $courierData['tel'],
            'country'   =>  $courierData['country'],
            'province'  =>  $courierData['province'],
            'city'      =>  $courierData['city'],
            'county'    =>  $courierData['county'],
            'address'   =>  $courierData['address']
        ];

        // 收件信息
        $orderAddress = [
            'contactType' => 2,
            'contact'     => $order['name'],
            'tel'         => $order['mobile'],
            'country'     => 'CN',
            'province'    => $order['province'],
            'city'        => $order['city'],
            'county'      => $order['district'],
            'address'     => $order['address'],
        ];
        $data = [
            'language' => 'zh-CN',
            'orderId'  => $order['order_sn'],
            'cargoDetails' => [
                'name' => '汽车配件'
            ],
            'contactInfoList' => [
                0 => $courier,       // 寄件方信息
                1 => $orderAddress // 收件方信息
            ],
            'monthlyCard'   => '7551234567',
            'expressTypeId' => 1,
            'payMethod'     => $payMethod
        ];

        $data = json_encode($data);
        $post = [
            'partnerID'   => $this->partnerid,
            'requestID'   => $asscessToken['requestID'],
            'serviceCode' => 'EXP_RECE_CREATE_ORDER',
            'timestamp'   => time(),
            'accessToken' => $asscessToken['accessToken'],
            'msgData'     => $data
        ];
        $post_url = $this->url.'/std/service';
        $datas    = request_url($post_url,$post);
        $response = json_decode($datas,true);

        $response['apiResultCode'] = 'A1000';
        if ($response['apiResultCode'] == 'A1000')
        {
            $ResultData = json_decode($response['apiResultData'],true);

            if ($ResultData['errorCode'] == "S0000" && $ResultData['success'] == true)
            {
                $responseCourier = $this->courierData($order,$courierData,$ResultData['msgData'],$admin_id);
                if ($responseCourier['status'] == true)
                {
                    $result['msg']    = $responseCourier['msg'];
                    $result['status'] = $responseCourier['status'];
                }else{
                    $result['msg']    = $responseCourier['msg'];
                    $result['status'] = $responseCourier['status'];
                }

            }else{
                $result['msg'] = $ResultData['errorMsg'];
            }
        }else{
            $result['msg'] = '下单失败';
        }
        return $result;

    }

    /**
     * 添加快递信息
     * $order 订单信息
     * $courier 发货信息
     * $ResultData 顺丰返回运单信息
     * $admin_id 操作人员
     */
    public function courierData($order,$courier,$ResultData,$admin_id = '')
    {
        $time = time();
        $result = [
            'data'      => [],
            'msg'       => '',
            'status'    => false
        ];

        Db::startTrans();
        try{
            $courierData = Db::name('courier')->where('orderid',$order['id'])->find();
            if ($courierData && $courierData['filterResult'])
            {
                $result['msg'] = '订单已提交发货';
                Db::rollback();
            }else{
                 $courierUpdate = [
                     'waybill'        => $ResultData['waybillNoInfoList'][0]['waybillNo'],
                     'filterResult'   => $ResultData['filterResult'],
                     'remark'         => $ResultData['remark'],
                     'updatetime'     => $time
                 ];
                if ($admin_id)
                {
                    $courierUpdate['admin_id'] = $admin_id;
                }
                 $courierInfo = Db::name('courier')
                     ->where('id',$courier['id'])
                     ->where('order_pay_sn',$courier['order_pay_sn'])
                     ->update($courierUpdate);

                if ($courierInfo)
                {
                    Db::name('order')->where('id',$order['id'])->update([
                        'order_status'     => 2,
                        'shipping_status'  => 1,
                        'shipping_time'    => $time,
                        'delivery_id'      => $ResultData['waybillNoInfoList'][0]['waybillNo'],
                        'delivery_name'    => '顺丰快递',
                    ]);
                    $result['msg'] = '发货成功';
                    $result['status']   = true;
                    Db::commit();
                }else{
                    $result['msg'] = '订单创建失败';
                    Db::rollback();
                }
            }
        }catch(\Exception $e)
        {
            echo $e->getMessage();
            Db::rollback();
        }

        return $result;
    }

    /**
     * 查询订单
     * $orderData 订单信息
     */
    public function courierQuery($orderData)
    {

        $result = [
            'data' => '',
            'msg'  => '',
            'status' => false
        ];
        $time = time();
        $post_url = $this->url.'/std/service';
        $accesst = $this->accessTokne();
        if ($accesst == false)
        {
            $result['msg'] = 'token请从新获取';
            return $result;
        }


        if ($accesst['apiResultCode'] != 'A1000')
        {
            $result['msg'] = '获取失败,请从新获取';
            return $result;
        }

        $data  = [
            'orderId'    => $orderData['pay_sn'],
            'searchType' => 1
            ];
        $data = json_encode($data);

        $post = [
            'partnerID'   => $this->partnerid,
            'requestID'   => $accesst['apiResponseID'],
            'serviceCode' => 'EXP_RECE_SEARCH_ORDER_RESP',
            'timestamp'   => $time,
            'accessToken' => $accesst['accessToken'],
            'msgData'     => $data
        ];

        $data = request_url($post_url, $post);
        $data = json_decode($data,true);

        if ($data['apiResultCode'] == 'A1000')
        {
            $apiResultData = json_decode($data['apiResultData'],true);

            if ($apiResultData['success'] == true)
            {
                 $courierRes= Db::name('courier')
                    ->where('order_pay_sn',$apiResultData['msgData']['orderId'])
                    ->find();
                 if ($courierRes)
                 {
                     if ($courierRes['waybill'])
                     {
                         $result['msg'] = '已下单';
                     }else{

                        $response = $this->courierData($orderData,$courierRes,$apiResultData['msgData']);
                        $result['status'] = $response['status'];
                        var_dump(66);
                        $result['msg']    = $response['msg'];
                     }
                 }else{
                     $result['msg'] = '未查询到发货信息';
                 }
            }else{
                $result['msg'] = $apiResultData['errorMsg'];
            }
        }else{
            $result['msg'] = $data['apiErrorMsg'];
        }
        return $result;
    }

    /**
     * 查询收件物流信息
     */
    public function filterReceipt($courier)
    {

        $result = [
            'data' => '',
            'msg'  => '',
            'status' => false
        ];
        $accesstoken = $this->sfAccesstoken();

        if (empty($accesstoken['accessToken']))
        {
            $result['msg'] = '认证获取失败';
            return $result;
        }

        $post_url = $this->url.'/std/service';
        $time = time();

        $data = [
            'trackingType' => '2',
            'trackingNumber' => $courier['order_pay_sn']
        ];


        $data = json_encode($data,true);
        $post = [
            'partnerID' => $this->partnerid,
            'requestID' => $accesstoken['requestID'],
            'serviceCode' => 'EXP_RECE_SEARCH_ROUTES',
            'timestamp'   => $time,
            'accessToken' => $accesstoken['accessToken'],
            'msgData'     => $data
        ];

        $response_data = request_url($post_url,$post);

        $response_data = json_decode($response_data, true);

        if ($response_data['apiResultCode'] == 'A1000')
        {
            $apiResultData = json_decode($response_data['apiResultData'],true);

            if (!empty($apiResultData['msgData']['routeResps'][0]))
            {
                $result['status'] = true;
                $result['msg']  = $apiResultData['msgData']['routeResps'][0]['routes'][0]['remark'];
                $result['data'] = $apiResultData['msgData']['routeResps'];
            }else{
                $result['msg'] = ['暂未收件'];
            }
        }else{
            $result['msg'] = $response_data['apiErrorMsg'];
        }
        return $result;
    }

    /**
     * 取消发货
     */
    public function orderCancel($waybill = '')
    {
        $result = [
            'data' => '',
            'msg'  => '',
            'status' => false
        ];
        $post_url = $this->url .'/std/service';
        $time = time();
        $accesstoken = $this->sfAccesstoken();

        if (empty($accesstoken['accessToken']))
        {
            $result['msg'] = '认证获取失败';
            return $result;
        }

        $data = [
            'orderId' => $waybill,
            'dealType' => 2,
        ];

        $data = json_encode($data);
        $post = [
            'partnerID'   => $this->partnerid,
            'requestID'   => $accesstoken['requestID'],
            'serviceCode' => 'EXP_RECE_UPDATE_ORDER',
            'timestamp'   => $time,
            'accessToken' => $accesstoken['accessToken'],
            'msgData'     => $data,
        ];

        $response_data = request_url($post_url,$post);
        $response_data = json_decode($response_data,true);
        if ($response_data['apiResultCode'] == 'A1000')
        {
            $apiResultData = json_decode($response_data['apiResultData'],true);
            if ($apiResultData['success'] == true)
            {
                if ($apiResultData['msgData']['resStatus'] == 2)
                {
                    $result['status'] = true;
                    $result['msg']    = '订单取消成功';
                    $result['data']   = $apiResultData['msgData']['orderId'];
                    return $result;
                }else{
                    $result['msg'] = '客户订单号与顺丰运单不匹配';
                    return $result;
                }
            }else{

                $result['msg'] = $apiResultData['errorMsg'];
                return $result;
            }

        }else{
            $result['msg'] = $response_data['apiErrorMsg'];

            return $result;
        }


    }

    /**
     * 打印
     */
    public function orderPrint()
    {

        $post_url = $this->url.'/std/service';

        $accesstoken = $this->sfAccesstoken();

        if (empty($accesstoken['accessToken']))
        {
            $result['msg'] = '认证获取失败';
            return $result;
        }

        $data = [
            'templateCode' => 'fm_150_standard_ACTWLiPz9EgL',
            'documents'    => [
                'masterWaybillNo' => 'SF7444459508372'
            ],
            'version' => '2.0',
            'fileType' => 'pdf',
            'sync' => 'true',
        ];
        $data = json_encode($data);
        $post = [
            'partnerID'   => $this->partnerid,
            'requestID'   => $accesstoken['requestID'],
            'serviceCode' => 'COM_RECE_CLOUD_PRINT_WAYBILLS',
            'timestamp'   => time(),
            'accessToken' => $accesstoken['accessToken'],
            'msgData'     => $data
        ];
        $response = request_url($post_url,$post);
        $response = json_decode($response,true);
        echo '<pre>';
        var_dump($response);
        $apiResultData = json_decode($response['apiResultData'],true);

        halt($apiResultData['obj']['files']);
    }




    /**
     * 获取电子模板编码
     */
    public function printCoding()
    {
        $post_url = $this->url.'/std/service';
        $accesstoken = $this->sfAccesstoken();
        if (empty($accesstoken['accessToken']))
        {
            $result['msg'] = '认证获取失败';
            return $result;
        }
        $data = [
            'standardTemplateCode' => '',
            'sellerUserId'         => '15901212181',
            'sellerUserId'         => 0,
        ];
        $data = json_encode($data);
        $post = [
            'partnerID'   => $this->partnerid,
            'requestID'   => $accesstoken['requestID'],
            'serviceCode' => 'COM_RECE_CLOUD_CUSTOMTEMPLATE_LIST',
            'timestamp'   => time(),
            'accessToken' => $accesstoken['accessToken'],
            'msgData'     => $data
        ];

        $response = request_url($post_url,$post);

        $response = json_decode($response,true);
        return $response;
    }
}